/**
 * 仕兰微电子 SC7A20 G-Sensor 接口定义
 * Copyright (c) 2021 深圳市智辰科技有限公司
 * All rights reserved.
 */

#ifndef _SC7A20_DEFS_H_
#define _SC7A20_DEFS_H_

#include "stdc.h"


/// 芯片标识(从 GS_REG_WHO_AM_I 读出来的值，应该与此相同)
#define GS_WHO_AM_I			0x11

/**
 * SPI 寄存器地址定义
 */
#define GS_REG_WHO_AM_I			0x0F

#define GS_REG_CTRL1			0x20
#define GS_REG_CTRL2			0x21
#define GS_REG_CTRL3			0x22
#define GS_REG_CTRL4			0x23
#define GS_REG_CTRL5			0x24
#define GS_REG_CTRL6			0x25

#define GS_REG_STATUS			0x27
		
#define GS_REG_OUT_X			0x28	// 16bits
#define GS_REG_OUT_Y			0x2A	// 16bits
#define GS_REG_OUT_Z			0x2C	// 16bits
	
#define GS_REG_FIFO_CTRL		0x2E
#define GS_REG_FIFO_SRC			0x2F

#define GS_REG_AOI1_CTRL		0x30
#define GS_REG_AOI1_SRC			0x31
#define GS_REG_AOI1_THS			0x32
#define GS_REG_AOI1_DURATION	0x33

#define GS_REG_AOI2_CTRL		0x34
#define GS_REG_AOI2_SRC			0x35
#define GS_REG_AOI2_THS			0x36
#define GS_REG_AOI2_DURATION	0x37

#define GS_REG_CLICK_CTRL		0x38
#define GS_REG_CLICK_SRC		0x39
#define GS_REG_CLICK_THS		0x3A

#define GS_REG_TIME_LIMIT		0x3B
#define GS_REG_TIME_LATENCY		0x3C
#define GS_REG_TIME_WINDOW		0x3D

#define GS_REG_MAX				0x3D

#pragma pack(push, 1)

typedef struct {
	uint8_t addr;
	uint8_t value;
} sc7a20_reg_t;

/*
ODR3 ODR2 ODR1 ODR0 电源模式选择
0 0 0 0 电源关断模式
0 0 0 1 正常 l / 低功耗模式(1 Hz)
0 0 1 0 正常 l / 低功耗模式(10 Hz)
0 0 1 1 正常 l / 低功耗模式(25 Hz)
0 1 0 0 正常 l / 低功耗模式(50 Hz)
0 1 0 1 正常 l / 低功耗模式(100 Hz)
0 1 1 0 正常 l / 低功耗模式(200 Hz)
0 1 1 1 正常 l / 低功耗模式(400 Hz)
1 0 0 0 低功耗模式 (1.6 KHz)
1 0 0 1 正常工作模式 (1.25 kHz) / 低功耗模式(5 KHz)

备注：在传感器正常工作时，关于 ODR 需要注意以下三点：
1)，低 ODR 向高 ODR 切换时，需要先配置为 0x97（1.25k 正常模式） ，然后配置到预先想要设置的高 ODR。
2)，DLPF_EN 打开后，传感器开始工作后需要 7 个 ODR 时钟后才能将第一个数据输出到寄存器中。
3)，在 ODR 较小时，DLPF_EN 置 1 后会一定程度影响运动物体的加速度幅值。
*/
#define MODE_POWER_OFF		0x08
#define ODR_NORMAL_1HZ		0x01
#define ODR_NORMAL_10HZ		0x02
#define ODR_NORMAL_25HZ		0x03
#define ODR_NORMAL_50HZ		0x04
#define ODR_NORMAL_100HZ	0x05
#define ODR_NORMAL_200HZ	0x06
#define ODR_NORMAL_400HZ	0x07
#define ODR_NORMAL_1600HZ	0x08
#define ODR_NORMAL_1250HZ	0x09

typedef struct {
	uint8_t Xen:1;	///< X 轴使能，默认值为 1。(0: 禁止，1：使能)
	uint8_t Yen:1;	///< Y 轴使能，默认值为 1。(0: 禁止，1：使能)
	uint8_t Zen:1;	///< Z 轴使能，默认值为 1。(0: 禁止，1：使能)
	uint8_t LPen:1;	///< 低功耗使能，默认值为 0。(0：正常工作模式，1：低功耗模式)
	uint8_t ODR:4;	///< 数据率选择，默认值：0000(电源关断模式)。
} gs_reg_ctrl1_t;

typedef struct {
	uint8_t HPIS1:1;		///< AOI1数据高通滤波使能。(0：滤波禁止； 1：滤波使能)
	uint8_t HPIS2:1;		///< AOI2数据高通滤波使能。(0：滤波禁止； 1：滤波使能)
	uint8_t HPCLICK:1;	///< CLICK 功能高通滤波使能。(0：滤波禁止； 1：滤波使能)
	uint8_t FDS:1;		///< 数据滤波选择。默认值：0。(0：跳过内部滤波； 1：内部滤波以后的数据输出到数据寄存器或 FIFO
	uint8_t HPCF:2;		///< 高通截止频率选择
	uint8_t HPM:2;		///< 高通模式选择。默认值：00；(0:正常模式 (读高通滤波自动复位)；1:滤波参考信号；2:正常模式；3:中断事件自动复位)
} gs_reg_ctrl2_t;

typedef struct {
	uint8_t _res: 1;
	uint8_t I1_OVERRUN: 1;	///< FIFO 溢出中断在 INT1 脚上。默认值：0(0：禁止； 1：使能)
	uint8_t I1_WTM:1;		///< FIFO WTM中断在 INT1 脚上。默认值：0(0：禁止； 1：使能)
	uint8_t I1_DRDY2:1;		///< DRDY2 中断在 INT1 脚上。默认值：0(0：禁止； 1：使能)
	uint8_t I1_DRDY1:1;		///< DRDY1 中断在 INT1 脚上。默认值：0(0：禁止； 1：使能)
	uint8_t I1_AOI2:1;		///< AOI2 中断在 INT1 脚上。默认值：0(0：禁止； 1：使能)
	uint8_t I1_AOI1:1;		///< AOI1 中断在 INT1 脚上。 默认值：0(0：禁止； 1：使能)
	uint8_t I1_CLICK:1;		///< CLICK 中断在 INT1 脚上。默认值：0(0：禁止； 1：使能)
} gs_reg_ctrl3_t;

typedef struct {
	uint8_t SIM:1;		///< SPI 串行接口模式配置。默认值：0(0：4 线接口； 1：3线接口)
	uint8_t ST:2;		///< 自测试使能。默认值：00(00: 自测试禁止；01：自测试0；02：自测试1)
	uint8_t DLPFen;		///< 数字低通滤波器使能。默认值：0(0： 禁止； 1：使能)
	uint8_t FS:2;		///< 全量程选择。默认值：00(00： +/- 2G； 01： +/- 4G； 10： +/- 8G； 11： +/- 16G)
	uint8_t BLE:1;		///< 大端/小端数据选择。默认值：0(0：低字节数据在低地址；1：高字节数据在低地址)
	uint8_t BDU:1;		///< 块数据更新。默认值：0(0：连续更新；1：输出数据寄存器不更新直到 MSB 和 LSB 被读取)
} gs_reg_ctrl4_t;

typedef struct {
	uint8_t AOI2_D4D:1;	///< 4D 使能： 使能 AOI2 上 4D 检测，需要同时要把 AOI2 配置寄存器中的6D 为置1。
	uint8_t AOI2_LIR:1;	///< 锁存 AOI2 配置寄存器上指定中断功能的中断响应信号（PIN 脚的高低电平）。通过读 AOI2 中断状态寄存器可以清除相应锁存的中断响应信号。默认值：0(0： 不锁存中断信号； 1：锁存中断信号)
	uint8_t AOI1_D4D:1;	///< 4D 使能： 使能 AOI1 上 4D 检测，需要同时要把 AOI1 配置寄存器中的6D 为置1。
	uint8_t AOI1_LIR:1;	///< 锁存 AOI1 配置寄存器上指定中断功能的中断响应信号（PIN 脚的高低电平）。通过读 AOI1 中断状态寄存器可以清除相应锁存的中断响应信号。默认值：0(0： 不锁存中断信号； 1：锁存中断信号)
	uint8_t _res1:1;
	uint8_t _res2:1;
	uint8_t FIFOen:1;	///< FIFO 使能。默认值：0(0：FIFO 禁止； 1： FIFO 使能,需要同时使能FIFO 控制寄存器的 FIFO 模式才能正常工作)
	uint8_t BOOT:1;		///< 重载修调值。默认值：0(0：正常模式； 1：重载修调值)
} gs_reg_ctrl5_t;

typedef struct {
	uint8_t _res1:1;
	uint8_t H_LACTIVE:1; ///< 0：中断触发时输出高电平(默认低电平)；1：中断触发时输出低电平(默认高电平)
	uint8_t _res2:1;
	uint8_t _res3:1;
	uint8_t I2_BOOT:1;   ///< BOOT 状态在 INT2 脚上。 默认值：0(0：禁止； 1：使能)
	uint8_t I2_AOI2:1;   ///< AOI2 中断在 INT2 脚上。 默认值：0(0：禁止； 1：使能)
	uint8_t I2_AOI1:1;   ///< AOI1 中断在 INT2 脚上。 默认值：0(0：禁止； 1：使能)
	uint8_t I2_CLICK:1;  ///< CLICK 中断在 INT2 脚上。默认值：0(0：禁止； 1：使能)
} gs_reg_ctrl6_t;

typedef struct {
	uint8_t XDA  :1; ///< X 轴新的数据到来。 默认值：0(0：X 轴新的数据尚未转换完成；1： X轴新的数据转换完成)
	uint8_t YDA  :1; ///< Y 轴新的数据到来。 默认值：0(0：Y 轴新的数据尚未转换完成；1： Y 轴新的数据转换完成)
	uint8_t ZDA  :1; ///< Z轴新的数据到来。 默认值：0(0：Z 轴新的数据尚未转换完成；1： Z轴新的数据转换完成)
	uint8_t ZYXDA:1; ///< X, Y 和 Z 三个轴新的数据全都转换完成。默认值：0(0：三轴中至少某一轴的数据尚未转换完成； 1：三个轴新的数据全都转换完成)
	uint8_t XOR  :1; ///< X 轴新的数据已经覆盖老的数据。 默认值：0(0：X 轴新的数据尚未覆盖老的数据；1： X轴新的数据覆盖了老的数据)
	uint8_t YOR  :1; ///< Y 轴新的数据已经覆盖老的数据。 默认值：0(0：Y 轴新的数据尚未覆盖老的数据；1： Y 轴新的数据覆盖了老的数据)
	uint8_t ZOR  :1; ///< Z 轴新的数据已经覆盖老的数据。 默认值：0(0：Z 轴新的数据尚未覆盖老的数据；1： Z轴新的数据覆盖了老的数据)
	uint8_t ZYXOR:1; ///< X，Y和 Z 三个轴新的数据至少有一个已经覆盖老的数据。 默认值：0(0：三个轴中没有一个轴新的数据覆盖老的数据；1： 三个轴中至少有一个轴新的数据已经覆盖了老的数据)
				///< 查询新数据是否就位可采用如下条件进行判断：if((Read(0x27) & 0x0F) == 0x0F) {break;}
} gs_reg_status_t;

typedef struct {
	uint8_t FTH:5;	///< FIFO 功能 WTM阈值设置（当 FIFO 中的数据个数超过设定阈值时，FIFO 状态寄存器相应状态位会置“1”）
	uint8_t TR:1;	///< FIFO 触发模式选择。默认值：0。（0：AOI1 中断作为 FIFO 触发模式中断事件输入；1：AOI2 中断作为 FIFO 触发模式中断事件输入）
	// FIFO 模式选择。默认值：00
	// 	00: By-Pass模式（旁路模式，即不使用 FIFO 功能）
	// 	01: FIFO 模式 （缓存满未及时读取，新数据丢弃）
	// 	10: Stream 模式 （缓存满后，最早数据丢弃，添加新数据）
	// 	11: 触发模式 （AOI1 或者 AOI2 中断事件有效，从 stream 模式进入 FIFO 模式）
	uint8_t FM:2; 
} gs_reg_fifo_cfg_t;

typedef struct {	
	uint8_t FSS:5; 	///< 在 FIFO 中未读取数据的组数。当 FIFO 中的一组数据被读取时，该 FIFO 数据组数寄存器置会自动减一。
	uint8_t EMPTY:1;	///< 当 FIFO 中无数据时，EMPTY 位置“1” 。
	uint8_t OVER:1;	///< 当 FIFO 中的数据溢出时，OVER 位置“1” 。
	uint8_t WTM:1;	///< 当 FIFO 中的数据个数超过设定阈值时，WTM位置“1” 。
} gs_reg_fifo_src_t;

typedef struct {	
	uint8_t XDOWN:1;	///< X 轴低事件中断或者方向检测中断使能。默认值：0(0：禁止中断；1：使能中断)
	uint8_t XUP:1;	///< X 轴高事件中断或者方向检测中断使能。默认值：0(0：禁止中断；1：使能中断)
	uint8_t YDOWN:1;	///< Y 轴低事件中断或者方向检测中断使能。默认值：0(0：禁止中断；1：使能中断)
	uint8_t YUP:1;	///< Y 轴高事件中断或者方向检测中断使能。默认值：0(0：禁止中断；1：使能中断)
	uint8_t ZDOWN:1;	///< Z 轴低事件中断或者方向检测中断使能。默认值：0(0：禁止中断；1：使能中断)
	uint8_t ZUP:1;	///< Z 轴高事件中断或者方向检测中断使能。默认值：0(0：禁止中断；1：使能中断)
	uint8_t D6:1;	///< 6 个方向检测功能使能。默认值：0。参考“中断模式”
	uint8_t AOI:1;	///< 与/或中断事件。默认值：0。参考“中断模式”
} gs_reg_aoi_ctrl_t;

typedef struct {		
	uint8_t XL:1;	///< X 轴低。默认值：0(0：没有中断， 1：事件已经产生)
	uint8_t XH:1;	///< X 轴高。默认值：0(0：没有中断， 1：事件已经产生)
	uint8_t YL:1;	///< Y 轴低。默认值：0(0：没有中断， 1：事件已经产生)
	uint8_t YH:1;	///< Y 轴高。默认值：0(0：没有中断， 1：事件已经产生)
	uint8_t ZL:1;	///< Z 轴低。默认值：0(0：没有中断， 1：事件已经产生)
	uint8_t ZH:1;	///< Z 轴高。默认值：0(0：没有中断， 1：事件已经产生)
	uint8_t IA:1;	///< AOI 中断触发状态位。默认值：0(0：中断没有产生；1：一个或多个中断已经产生)
	uint8_t _res:1;
} gs_reg_aoi_src_t;

typedef struct {		
	uint8_t X:1;		///< X 轴检测到单双击。默认值：0(0：没有检测到中断； 1：检测到中断)
	uint8_t Y:1;		///< Y 轴检测到单双击。默认值：0(0：没有检测到中断； 1：检测到中断)
	uint8_t Z:1;		///< Z 轴检测到单双击。默认值：0(0：没有检测到中断； 1：检测到中断)
	uint8_t Sign:1;	///< 单双击检测到的符号。(0：检测到正方向； 1：检测到负方向)
	uint8_t SCLICK:1;///< 单击检测状态位。默认值：0(0：没有检测到单击； 1：检测到单击)
	uint8_t DCLICK:1;///< 双击检测状态位。默认值：0(0：没有检测到双击； 1：检测到双击)
	uint8_t IA:1;	///< 中断激活。默认值：0(0： 中断没有产生； 1：一个或多个中断已经产生)
	uint8_t _res:1;
} gs_reg_click_src_t;

#pragma pack(pop)


#endif // _SC7A20_DEFS_H_
